//////////////////////////////////////////////
// ImageDescriptor.js
//
//////////////////////////////////////////////

/// Class ------------------------------------
	
nkImagesTests.ImageDescriptor = class ImageDescriptor extends nkDebug.TestClass
{
	static instance = new ImageDescriptor ("nkImagesTests.ImageDescriptor") ;

	// Utils
	getMipDescriptorConstructor (managed)
	{
		return managed ? nkImages.MipDescriptor : nkImages.unmanaged.MipDescriptor ;
	}

	getImageDescriptorConstructor (managed)
	{
		return managed ? nkImages.ImageDescriptor : nkImages.unmanaged.ImageDescriptor ;
	}

	getBufferCastOrArrayLength (v, managed)
	{
		return managed ? v.length : v.getSize() ;
	}

	getBufferCastOrArrayElement (v, index, managed)
	{
		return managed ? v[index] : v.get(index) ;
	}

	// Common test methods
	// Constructor
	testDefaultConstructor (managed)
	{
		const ctor = ImageDescriptor.instance.getImageDescriptorConstructor(managed) ;
		const d = new ctor () ;

		nkDebug.TestUtils.check(nk.isUnmanagedInstance(d) == !managed, "Managed state unexpected") ;
		nkDebug.TestUtils.check(ImageDescriptor.instance.getBufferCastOrArrayLength(d._mips, managed) == 0, "Wrong mips array length") ;
		nkDebug.TestUtils.check(ImageDescriptor.instance.getBufferCastOrArrayLength(d._mipOffsets, managed) == 0, "Wrong mip offsets array length") ;

		if (!managed)
			d.delete() ;
	}

	testFullConstructor (managed, managedMips)
	{
		// Prepare data
		const mipCtor = ImageDescriptor.instance.getMipDescriptorConstructor(managedMips) ;

		let mips = [new mipCtor (), new mipCtor (10, 20, 5, 15, 300, 1500)] ;
		let mipOffsets = [0, 6000] ;

		if (!managed)
		{
			// Wrap into buffer casts
			mips = new nkMemory.unmanaged.BufferCast_nkImages_MipDescriptor (mips) ;
			mipOffsets = new nkMemory.unmanaged.BufferCast_unsigned_int (mipOffsets) ;
		}

		// Find constructor
		const ctor = ImageDescriptor.instance.getImageDescriptorConstructor(managed) ;
		const d = new ctor (mips, mipOffsets) ;

		nkDebug.TestUtils.check(nk.isUnmanagedInstance(d) == !managed, "Managed state unexpected") ;
		nkDebug.TestUtils.check(ImageDescriptor.instance.getBufferCastOrArrayLength(d._mips, managed) == 2, "Wrong mips array length") ;
		nkDebug.TestUtils.check(ImageDescriptor.instance.getBufferCastOrArrayLength(d._mipOffsets, managed) == 2, "Wrong mip offsets array length") ;
		
		const arrayIndexer = function (a, i) {return ImageDescriptor.instance.getBufferCastOrArrayElement(a, i, managed) ;} ;

		nkDebug.TestUtils.check(arrayIndexer(d._mipOffsets, 0) == arrayIndexer(mipOffsets, 0), "Wrong mip offset 0") ;
		nkDebug.TestUtils.check(arrayIndexer(d._mipOffsets, 1) == arrayIndexer(mipOffsets, 1), "Wrong mip offset 1") ;

		for (var i = 0 ; i < mips.length ; ++i)
		{
			const element = ImageDescriptor.instance.getBufferCastOrArrayElement(d._mips, i, managed) ;
			const reference = arrayIndexer(mips, i) ;
			nkDebug.TestUtils.check(nk.isUnmanagedInstance(element) == !managed, "Mip managed state unexpected") ;
			nkDebug.TestUtils.check(element._width == reference._width, "Wrong mip width " + i) ;
			nkDebug.TestUtils.check(element._height == reference._height, "Wrong mip height " + i) ;
			nkDebug.TestUtils.check(element._depth == reference._depth, "Wrong mip depth " + i) ;
			nkDebug.TestUtils.check(element._rowByteSize == reference._rowByteSize, "Wrong mip row byte size " + i) ;
			nkDebug.TestUtils.check(element._sliceByteSize == reference._sliceByteSize, "Wrong mip slice byte size " + i) ;
			nkDebug.TestUtils.check(element._fullByteSize == reference._fullByteSize, "Wrong mip full byte size " + i) ;
		}

		if (!managed)
		{
			mips.delete() ;
			mipOffsets.delete() ;
			d.delete() ;
		}
	}

	testCopyConstructor (managed0, managed1)
	{
		let mips = [new nkImages.MipDescriptor (), new nkImages.MipDescriptor (10, 20, 5, 15, 300, 1500)] ;
		let mipOffsets = [0, 6000] ;

		if (!managed0)
		{
			// Wrap into buffer casts
			mips = new nkMemory.unmanaged.BufferCast_nkImages_MipDescriptor (mips) ;
			mipOffsets = new nkMemory.unmanaged.BufferCast_unsigned_int (mipOffsets) ;
		}

		const ctor0 = ImageDescriptor.instance.getImageDescriptorConstructor(managed0) ;
		const ctor1 = ImageDescriptor.instance.getImageDescriptorConstructor(managed1) ;
		
		const d0 = new ctor0 (mips, mipOffsets) ;
		const d1 = new ctor1 (d0) ;

		nkDebug.TestUtils.check(nk.isUnmanagedInstance(d0) == !managed0, "Managed 0 state unexpected") ;
		nkDebug.TestUtils.check(nk.isUnmanagedInstance(d1) == !managed1, "Managed 1 state unexpected") ;
		nkDebug.TestUtils.check(ImageDescriptor.instance.getBufferCastOrArrayLength(d0._mips, managed0) == ImageDescriptor.instance.getBufferCastOrArrayLength(d1._mips, managed1), "Wrong mips array length") ;
		nkDebug.TestUtils.check(ImageDescriptor.instance.getBufferCastOrArrayLength(d0._mipOffsets, managed0) == ImageDescriptor.instance.getBufferCastOrArrayLength(d1._mipOffsets, managed1), "Wrong mip offsets array length") ;
		
		const arrayIndexer = function (a, i, managed) {return ImageDescriptor.instance.getBufferCastOrArrayElement(a, i, managed) ;} ;

		nkDebug.TestUtils.check(arrayIndexer(d0._mipOffsets, 0, managed0) == arrayIndexer(d1._mipOffsets, 0, managed1), "Wrong mip offset 0") ;
		nkDebug.TestUtils.check(arrayIndexer(d0._mipOffsets, 1, managed0) == arrayIndexer(d1._mipOffsets, 1, managed1), "Wrong mip offset 1") ;

		for (var i = 0 ; i < mips.length ; ++i)
		{
			const element0 = ImageDescriptor.instance.getBufferCastOrArrayElement(d0._mips, i, managed0) ;
			const element1 = ImageDescriptor.instance.getBufferCastOrArrayElement(d1._mips, i, managed1) ;
			nkDebug.TestUtils.check(nk.isUnmanagedInstance(element0) == !managed0, "Mip managed 0 state unexpected") ;
			nkDebug.TestUtils.check(nk.isUnmanagedInstance(element1) == !managed1, "Mip managed 1 state unexpected") ;
			nkDebug.TestUtils.check(element0._width == element1._width, "Wrong mip width " + i) ;
			nkDebug.TestUtils.check(element0._height == element1._height, "Wrong mip height " + i) ;
			nkDebug.TestUtils.check(element0._depth == element1._depth, "Wrong mip depth " + i) ;
			nkDebug.TestUtils.check(element0._rowByteSize == element1._rowByteSize, "Wrong mip row byte size " + i) ;
			nkDebug.TestUtils.check(element0._sliceByteSize == element1._sliceByteSize, "Wrong mip slice byte size " + i) ;
			nkDebug.TestUtils.check(element0._fullByteSize == element1._fullByteSize, "Wrong mip full byte size " + i) ;
		}

		if (!managed0)
		{
			mips.delete() ;
			mipOffsets.delete() ;
			d0.delete() ;
		}

		if (!managed1)
			d1.delete() ;
	}

	nkTests =
	{
		// Constructors
		DefaultConstructorUnmanaged : function () {ImageDescriptor.instance.testDefaultConstructor(false) ;},
		DefaultConstructorManaged : function () {ImageDescriptor.instance.testDefaultConstructor(true) ;},
		FullConstructorUnmanagedMipUnmanaged : function () {ImageDescriptor.instance.testFullConstructor(false, false) ;},
		FullConstructorUnmanagedMipManaged : function () {ImageDescriptor.instance.testFullConstructor(false, true) ;},
		FullConstructorManagedMipUnmanaged : function () {ImageDescriptor.instance.testFullConstructor(true, false) ;},
		FullConstructorManagedMipManaged : function () {ImageDescriptor.instance.testFullConstructor(true, true) ;},
		CopyConstructorUnmanagedUnmanaged : function () {ImageDescriptor.instance.testCopyConstructor(false, false) ;},
		CopyConstructorUnmanagedManaged : function () {ImageDescriptor.instance.testCopyConstructor(false, true) ;},
		CopyConstructorManagedUnmanaged : function () {ImageDescriptor.instance.testCopyConstructor(true, false) ;},
		CopyConstructorManagedManaged : function () {ImageDescriptor.instance.testCopyConstructor(true, true) ;},
	}
}